﻿using Vestras.StarCraft2.Luna.Parser;
using Vestras.StarCraft2.Luna.Parser.Ast;

namespace Vestras.StarCraft2.Luna.Validation {
    public sealed class WhileStatementTypeValidator : ITypeValidator {
        public System.Type[] Type {
            get {
                return new[] { typeof(WhileStatement) };
            }
        }

        public bool Validate(object value) {
            if (value != null && value is WhileStatement) {
                ErrorSink.UpdateChangeCollection();
                WhileStatement whileStatement = value as WhileStatement;
                if (!whileStatement.Condition.DoesExpressionResolveToType(DefaultTypeReferences.Bool)) {
                    if (!ErrorSink.HasChanged()) {
                        ErrorSink.AddError(ErrorSink.Error.Create("Cannot convert type '" + whileStatement.Condition.GetTypeQualifiedId() + "' to type '" + DefaultTypeReferences.Bool.GetQualifiedId() + "'", whileStatement));
                    }

                    return false;
                }

                bool childrenValid = true;
                foreach (Entity child in whileStatement.Children) {
                    if (child is Variable) {
                        ErrorSink.AddError(ErrorSink.Error.Create("Variables must be declared in the top of a function", child));
                        return false;
                    }

                    ITypeValidator typeValidator = ValidationEntryPoint.GetTypeValidatorForType(new[] { child.GetType() });
                    if (typeValidator != null) {
                        bool valid = typeValidator.Validate(child);
                        if (!valid) {
                            childrenValid = false;
                        }
                    }
                }

                return childrenValid;
            }

            return false;
        }
    }
}
